/*
 * 作者: junmu
 * 时间: 2025-07-22
 */
package com.hzbc.faceattendance.config;

import com.hzbc.faceattendance.security.CustomUserDetailsService;
import com.hzbc.faceattendance.security.JwtAuthenticationEntryPoint;
import com.hzbc.faceattendance.security.JwtAuthenticationFilter;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CommonsRequestLoggingFilter;

import java.util.Arrays;

@Configuration
@EnableWebSecurity
@Slf4j
public class SecurityConfig {

    private final CustomUserDetailsService userDetailsService;
    private final JwtAuthenticationEntryPoint unauthorizedHandler;

    public SecurityConfig(CustomUserDetailsService userDetailsService,
                          JwtAuthenticationEntryPoint unauthorizedHandler) {
        this.userDetailsService = userDetailsService;
        this.unauthorizedHandler = unauthorizedHandler;
    }

    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }

    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder())
                .and().build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setExposedHeaders(Arrays.asList("Authorization"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Bean
    public CommonsRequestLoggingFilter logFilter() {
        CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
        filter.setIncludeQueryString(true);
        filter.setIncludePayload(true);
        filter.setMaxPayloadLength(10000);
        filter.setIncludeHeaders(true);
        return filter;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .cors(cors -> cors.configurationSource(corsConfigurationSource()))  // 显式配置CORS
                .csrf(csrf -> csrf.disable())  // Lambda风格禁用CSRF
                .exceptionHandling(exceptions -> exceptions
                        .authenticationEntryPoint(unauthorizedHandler)  // 保留401处理
                        .accessDeniedHandler((request, response, ex) -> {  // 新增403处理
                            response.sendError(HttpStatus.FORBIDDEN.value(), "无访问权限");
                        })
                )
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)  // 无状态会话
                )
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/api/auth/login", "/api/auth/refresh-token").permitAll()
                        .requestMatchers("/api/auth/changePassword", "/api/auth/register", "/api/auth/onDutyConfig").hasAuthority("ROLE_1")
                        .requestMatchers("/api/**").authenticated()
                        .anyRequest().permitAll()
                );
        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

//    @Bean
//    @Primary
//    public TomcatServletWebServerFactory servletContainer(
//            @Value("${server.ssl.key-store}") String keyStore,
//            @Value("${server.ssl.key-store-password}") String keyStorePassword,
//            @Value("${server.ssl.key-store-type}") String keyStoreType,
//            @Value("${server.ssl.key-alias}") String keyAlias) {
//        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
//        log.info("Configuring Tomcat with SSL: keyStore={}, keyAlias={}", keyStore, keyAlias);
//        // 添加HTTP到HTTPS的重定向连接器
//        tomcat.addAdditionalTomcatConnectors(redirectConnector());
//        // 添加SSL配置
//        tomcat.addConnectorCustomizers(connector -> {
//            log.info("Customizing connector with SSL settings");
//            // 设置SSL属性 - 使用正确的方式
//            connector.setSecure(true);
//            connector.setScheme("https");
//            connector.setProperty("SSLEnabled", "true");
//            connector.setProperty("sslProtocol", "TLS");
//            connector.setProperty("keystoreFile", keyStore);
//            connector.setProperty("keystorePass", keyStorePassword);
//            connector.setProperty("keystoreType", keyStoreType);
//            connector.setProperty("keyAlias", keyAlias);
//            // For PKCS12 keystores, we might need to set additional properties
//            if ("PKCS12".equalsIgnoreCase(keyStoreType)) {
//                connector.setProperty("clientAuth", "false");
//                connector.setProperty("protocol", "HTTP/1.1");
//            }
//            // 您原有的自定义配置
//            connector.setProperty("connectionUploadTimeout", "1800000");
//            connector.setProperty("socket.soTimeout", "1800000");
//            connector.setProperty("keepAliveTimeout", "300000");
//        });
//
//        return tomcat;
//    }
//
//    private Connector redirectConnector() {
//        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
//        connector.setScheme("http");
//        connector.setPort(80);
//        connector.setSecure(false);
//        connector.setRedirectPort(443);
//        return connector;
//    }
}